package br.unifor.cct.mia.util.missingvalue;

import java.awt.Point;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

import br.unifor.cct.mia.dataenhancement.Attribute;
import br.unifor.cct.mia.dataenhancement.Database;
import br.unifor.cct.mia.dataenhancement.GenotypeConverter;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.dataenhancement.Tuple;
import br.unifor.cct.mia.evaluate.Evaluate;
import br.unifor.cct.mia.evaluate.classification.WekaClassification;
import br.unifor.cct.mia.util.LoadFile;
import br.unifor.cct.mia.util.Methods;
import br.unifor.cct.mia.util.SaveReport;

public class MissingValueMedia {

	private static String[] datasets = {"breast","car","dermatology",
		"diabetes","iris","zoo"};
	private static int porcentagens[] = {5,10,20,33};
	private static int pastas[] = {1,2,3};

	private static Integer[] learnerTypes = {Evaluate.J48, Evaluate.IBK, 
		Evaluate.NAIVE_BAYES, Evaluate.PART};
	private static FileWriter resultFile;

	public static void main(String[] args) throws IOException {

		DecimalFormat df = new DecimalFormat("##.##");

		for (String dbName: datasets) {

			for ( int p:pastas) {

				String path = "./Convertidas/"+dbName+"/Estratificado/20/MV"+p+"/";
				String strucFile = path+dbName+"_struc.txt";
				String testFilePath = path+dbName+"_data_test.txt";		

				Structure st = LoadFile.loadStructure(strucFile);
				Database dbTeste = LoadFile.loadDatabase(testFilePath);

				String resultFilePath = path+"RESULTADO_MEDIA.txt";	
				resultFile = new FileWriter(resultFilePath);


				for ( int m:porcentagens ) {
					for ( int n=1; n<=5; n++ ) {
						String dbFile = null;
						if ( m==5 )
							dbFile = path+dbName+"_data_MV-0"+m+"_"+n+".txt";
						else
							dbFile = path+dbName+"_data_MV-"+m+"_"+n+".txt";

						Date d0 = new Date();

						Database db = LoadFile.loadDatabase(dbFile);

						List positions = LoadFile.getFaultDatabase(st, db);
						Tuple tuples = new Tuple();
						db.mountStr(tuples, positions);

						String[] valores = new String[st.size()];
						for(int i=0; i<st.size(); i++) {
							Attribute att = st.getAttribute(i);

							if ( att.getTipo().equalsIgnoreCase(Attribute.CONTINUOUS) ) {
								double sun = 0;
								int count = 0;
								for(int j=0; j<db.size(); j++) {
									String v = db.getElement(j, i);
									if ( v!=null && !v.equals("?") ) {
										sun += Double.parseDouble(v);
										count++;								
									}
								}
								if ( att.isInteger() ) {
									valores[i] = String.valueOf( (int)(sun/count) );
								}
								else {
									valores[i] = String.valueOf( (double)((double)sun/(double)count) );
								}
							}
							else {
								List values = st.getValues(i);
								int[] count = new int[values.size()];

								for(int j=0; j<db.size(); j++) {
									String v = db.getElement(j, i);
									if ( v!=null && !v.equals("?") ) {
										int index = values.indexOf(v);
										count[index]++;
									}
								}

								int pos = Methods.arrayMaximunPos(count);
								valores[i] = (String)values.get(pos);
							}
						}

						String[] valoresFinal = new String[positions.size()];
						for (int i=0;i<positions.size();i++) {
							Point point = (Point)positions.get(i);
							valoresFinal[i] = valores[point.y]; 
						}

						try { 
							SaveReport report = new SaveReport("temp/result_mv.txt",st.getStrucFile());
							report.addLine(tuples.string(st.getStringValues(positions, valoresFinal )));
							report.saveToDisk();

							for ( Integer learnerType: learnerTypes ) {
								WekaClassification classificator = new WekaClassification(learnerType,null);
								double result = classificator.evaluate(report.getFile());

								GenotypeConverter converter = new GenotypeConverter();
								File fileTest = converter.fullConvert("temp/resultFinalTeste_MV.txt", st, dbTeste);

								classificator = new WekaClassification(learnerType,null);
								double test = classificator.evaluate(report.getFile(),fileTest);

								Date d1 = new Date();

								String line = "["+getEvaluateValue(learnerType)+"]; "
								+ "[m="+m+"]; "
								+ df.format(result) + ";" 
								+ df.format(test) + ";" 
								+ String.valueOf((d1.getTime() - d0.getTime()) / 1000);

								System.out.println(line);

								resultFile.write(line+"\n");
								resultFile.flush();
							}
						}
						catch (Exception e) {
							e.printStackTrace();
						}			
					}
				}

				resultFile.close();
			}

		}
	}

	/*
	public static Integer J48 = new Integer(1);
	public static Integer MULTILAYER_PERCEPTRON = new Integer(2);
	public static Integer NAIVE_BAYES = new Integer(3);
	public static Integer IBK = new Integer(4);
	public static Integer PART = new Integer(5);
	 */
	private static String getEvaluateValue(int value) {

		String result = "";
		switch (value) {
		case 1:
			result = "J48";
			break;
		case 2:
			result = "MULTILAYER_PERCEPTRON";
			break;
		case 3:
			result = "NAIVE_BAYES";
			break;
		case 4:
			result = "IBK";
			break;
		case 5:
			result = "PART";
			break;
		case 6:
			result = "RBF NETWORK";
			break;
		}
		return result;
	}

}
